<?php
namespace app\index\controller;
use app\index\controller\Basewx;
use app\service\apiService;
use app\service\orderService;
use think\Controller;
use think\request;
use think\Db;
use think\facade\Log;
error_reporting(0);
//
class Orderwx extends Controller{
    public function carquery(){
        if(!session("user_id")){
            $code = request()->get('code');
    		$appid="wx3fd7e9c4152f4823";
    		$secret="dfc5e75de83b93d8abb1d41aeced2a72"; 
    		//用通过code换取网页授权access_token，同时获得openid
            $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$appid.'&secret='.$secret.'&code='.$code.'&grant_type=authorization_code';
    		$userinfo=$this->getJson($url);
    		//var_dump($userinfo);
    		if(!empty($userinfo['errmsg'])){
                return $userinfo['errmsg'];
            }
            session("user_id",$userinfo['openid']);
        }
        
        $this->assign("user_id",session("user_id"));
        $parkingNo=request()->get("parkingNo");
        $this->assign("parkingNo",$parkingNo);
        return $this->fetch();
    }
    public function prepay(){
        
        $parkingNo=request()->get("parkingNo");
	    $user_id=request()->get("user_id");
	    $carPlateNo=request()->get("car_number");
	    //查询客户端是否在线
	    $clientinfo=Db::table("client_login")->where("parkingNo",$parkingNo)->where("connect_status","ON")->find();
	    if(empty($clientinfo)){
	        return "客户端不在线";
	    }
	    
	    //查询停车入场信息
	    $carinfo=Db::table("car_order_in")->where("parkingNo",$parkingNo)->where("carPlateNo",$carPlateNo)->order("id","desc")->limit("1")->find();
	    if(empty($carinfo)){
	        return $this->fetch("nomsgpre");
	    }
	    $client=new \swoole_client(SWOOLE_SOCK_TCP);
	    
        if(!$client->Connect("47.106.184.188",9500,0.5)){
            echo "errCode:".$client->errCode."\r\n";
            die("connect failed\r\n");
        }
        $msg='{"bizCode":"Pre1015","parkingNo":"'.$parkingNo.'","clientNo":"'.$clientinfo["clientNo"].'","carPlateNo":"'.$carPlateNo.'","parkingOrderNo":"'.$carinfo["parkingOrderNo"].'","outParkingOrderNo":"'.$carinfo["outParkingOrderNo"].'"}';
        $client->send($msg."\r\n");
        //从服务端接收信息
        $data=$client->recv();
        
        if(!$data){
            return $this->fetch("nomsgpre");
            return "查询失败,请稍后再试";
            die("recv failed \r\n");
        }
        
        $client->close();
        $orderinfo=json_decode($data,true);
        if($orderinfo["bizCode"]=="B1016"){
            if($orderinfo["respCode"]!="00000"){
                return "<div style='font-size:60px;text-align:center;margin-top:50px'>".$orderinfo["respMsg"]."</div>";
            }
        }
        
        $parkinginfo=Db::table("parkinglotinfo")->where("parkingNo",$orderinfo["parkingNo"])->find();
        
        $this->assign("parkinginfo",$parkinginfo);
        unset($orderinfo["respMsg"]);
        unset($orderinfo["respCode"]);
        unset($orderinfo["sign"]);
        unset($orderinfo["bizCode"]);
        $orderinfo["parkingName"]=$parkinginfo["parkingName"];
        $orderinfo["user_id"]=$user_id;
        $orderinfo["payType"]=9;
        //$orderinfo["outChannelNo"]=$caminfo["channelNo"];
        //echo "<pre>";
        //var_dump($orderinfo);die;
        $pay_id=Db::name('car_order_query')->insertGetId($orderinfo);
        $this->assign("pay_id",$pay_id);
        $this->assign("orderinfo",$orderinfo);
	    return $this->fetch();
    }
    
    public function prepayOrder(){
		//根据ID查询停车场信息
		$pay_id=request()->post("pay_id");
		$orderinfo=Db::table("car_order_query")->where("id",$pay_id)->find();
		if(empty($orderinfo)){
		    return json(['info' => "查询账单失败"]);
		}
		if($orderinfo["payStatus"]=="SUCCESS"){
			return json(['info' => '缴费成功']);
		}
		
	
		//生成订单
		$data['appid'] = "wx3fd7e9c4152f4823";//公众账号ID
		$data['mch_id'] ="1484539292";//
		//根据停车场商户ID
		$data['sub_mch_id'] =(new orderService())->getmchid($orderinfo["parkingNo"]);
		$data['nonce_str'] = $this->createNoncestr();//随机字符串
		$data['body'] = $orderinfo["parkingName"]."-".$orderinfo["carPlateNo"]."-".date('Y-m-d H:i:s');//商品描述
		$data['out_trade_no'] = date('YmdHiss').rand(100000,999999);//商户订单号
		$data['total_fee'] = $orderinfo["amountRec"];//总金额
		//$data['total_fee']=1;
		$data['spbill_create_ip'] = $_SERVER["REMOTE_ADDR"];//终端IP
		$data['notify_url'] = 'http://www.aliwgzf.com/index/callback/wxprenotice';//通知url
		$data['trade_type'] = 'JSAPI';
		$data['openid'] = $orderinfo['user_id'];//用户标识
		
		$wxkey="asdfaASDFASDFASFasfsadf6546A84SA";
		$data['sign'] = $this->MakeSign($data,$wxkey);//签名
		// return json(['info' => $data]);
		//输出xml字符
	
		$xml = $this->ToXml($data);
		
		$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
		//CURL模拟请求
		$curls = curl_init(); //启动一个CURL会话
		curl_setopt($curls, CURLOPT_URL, $url); //要访问的地址
		curl_setopt($curls, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($curls, CURLOPT_SSL_VERIFYHOST, FALSE);
		curl_setopt($curls, CURLOPT_HEADER, FALSE);//设置header
		curl_setopt($curls, CURLOPT_RETURNTRANSFER, TRUE);//要求结果为字符串且输出到屏幕上
		curl_setopt($curls, CURLOPT_POST, TRUE); //发送一个常规的Post请求
		curl_setopt($curls, CURLOPT_POSTFIELDS, $xml); //Post提交的数据包
		curl_setopt($curls, CURLOPT_TIMEOUT, 30); //设置超时限制防止死循环
		$payInfo = curl_exec($curls); //执行操作
		// $err = curl_error($curls);//输出错误
		curl_close($curls); //关闭CURL会话
		
		 //$payInfo = (new wechatService())->post_curl_data($url,$xml);
		$payInfo = json_decode(json_encode(simplexml_load_string($payInfo, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
		header("Content-type:text/html;charset=utf8");
		
		if($payInfo['return_code'] !== 'SUCCESS'){
			//return json(['info' => $payInfo]);
			Log::write($payInfo,"123456");
			return json(['info' => $payInfo['return_msg']]);
		}else{
			//添加进数据库
		    unset($orderinfo["id"]);
		    $order=$orderinfo;
			$order['out_trade_no'] = $data['out_trade_no'];
		    $order['tradeno'] = $data['out_trade_no'];
			$order["subject"]=$data['body'];
			$res=Db::table("car_order_pay")->insert($order);
			if($res){
			    $jsApiParameters['appId'] = $payInfo['appid'];
				$jsApiParameters['timeStamp'] = time();
				$jsApiParameters['timeStamp'] = '$jsApiParameters["timeStamp"]';
				$jsApiParameters['nonceStr'] = $this->createNoncestr();
				$jsApiParameters['package'] = 'prepay_id='.$payInfo['prepay_id'];
				$jsApiParameters['signType'] = 'MD5';
				$jsApiParameters['paySign'] = $this->MakeSigns($jsApiParameters,$wxkey);
				return json(['jsApiParameters' => json_encode($jsApiParameters)]);
			}else{
				return json(['info' => '订单存储失败']);
			}
		}   
	}
    
    public function outpay(){
        $code = request()->get('code');
		$appid="wx3fd7e9c4152f4823";
		$secret="dfc5e75de83b93d8abb1d41aeced2a72"; 
		//用通过code换取网页授权access_token，同时获得openid
        $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$appid.'&secret='.$secret.'&code='.$code.'&grant_type=authorization_code';
		$userinfo=$this->getJson($url);
		//var_dump($userinfo);
		if(!empty($userinfo['errmsg'])){
            return $userinfo['errmsg'];
        }
        $cam_id=request()->get("cam_id");
	    $caminfo=Db::table("parking_camera")->where("id",$cam_id)->find();
	    if(empty($caminfo)){
	        return "相机信息错误";
	    }
	    $this->assign("caminfo",$caminfo);
	    
	    //查询客户端是否在线
	    $clientinfo=Db::table("client_login")->where("clientNo",$caminfo["clientNo"])->where("parkingNo",$caminfo["parkingNo"])->find();
	    if(empty($clientinfo)){
	        return "客户端不在线";
	    }
	    if($clientinfo["connect_status"]=="OFF"){
            return $this->fetch("order/offline");
	        return "客户端不在线";
	    }
	    $client=new \swoole_client(SWOOLE_SOCK_TCP);
	    //$client=new \Swoole\Coroutine\Client(SWOOLE_SOCK_TCP);
	    /*$client->set([
	        'timeout' => 0.5,
            'connect_timeout' => 1.0,
            'write_timeout' => 1,
            'read_timeout' => 1,
        ]);*/
        if(!$client->Connect("47.106.184.188",9500,0.5)){
            echo "errCode:".$client->errCode."\r\n";
            die("connect failed\r\n");
        }
        $msg='{"bizCode":"C1015","parkingNo":"'.$caminfo["parkingNo"].'","clientNo":"'.$caminfo["clientNo"].'","cam_id":"'.$caminfo["channelNo"].'"}';
        $client->send($msg."\r\n");
        //从服务端接收信息
        $data=$client->recv();
        if(!$data){
            return $this->fetch("nomsg");
            return "查询失败,请稍后再试";
            die("recv failed \r\n");
        }
        $client->close();
        $orderinfo=json_decode($data,true);
        if($orderinfo["bizCode"]=="B1016"){
            if($orderinfo["respCode"]!="00000"){
                return $orderinfo["respMsg"];
            }
        }
        
        $parkinginfo=Db::table("parkinglotinfo")->where("parkingNo",$orderinfo["parkingNo"])->find();
        
        $this->assign("parkinginfo",$parkinginfo);
        unset($orderinfo["respMsg"]);
        unset($orderinfo["respCode"]);
        unset($orderinfo["sign"]);
        unset($orderinfo["bizCode"]);
        $orderinfo["parkingName"]=$parkinginfo["parkingName"];
        $orderinfo["user_id"]=$userinfo['openid'];
        $orderinfo["outChannelNo"]=$caminfo["channelNo"];
        //echo "<pre>";
        //var_dump($orderinfo);die;
        $pay_id=Db::name('car_order_query')->insertGetId($orderinfo);
        $this->assign("pay_id",$pay_id);
        $this->assign("orderinfo",$orderinfo);
	    return $this->fetch();
    }
    
    
    
    
    
    
    public function createOrder(){
		//根据ID查询停车场信息
		$pay_id=request()->post("pay_id");
		$orderinfo=Db::table("car_order_query")->where("id",$pay_id)->find();
		if(empty($orderinfo)){
		    return json(['info' => "查询账单失败"]);
		}
		if($orderinfo["payStatus"]=="SUCCESS"){
			return json(['info' => '缴费成功']);
		}
		
	
		//生成订单
		$data['appid'] = "wx3fd7e9c4152f4823";//公众账号ID
		$data['mch_id'] ="1484539292";//
		//根据停车场商户ID
		$data['sub_mch_id'] =(new orderService())->getmchid($orderinfo["parkingNo"]);
		$data['nonce_str'] = $this->createNoncestr();//随机字符串
		$data['body'] = $orderinfo["parkingName"]."-".$orderinfo["carPlateNo"]."-".date('Y-m-d H:i:s');//商品描述
		$data['out_trade_no'] = date('YmdHiss').rand(100000,999999);//商户订单号
		$data['total_fee'] = $orderinfo["amountRec"];//总金额
		//$data['total_fee']=1;
		$data['spbill_create_ip'] = $_SERVER["REMOTE_ADDR"];//终端IP
		$data['notify_url'] = 'http://www.aliwgzf.com/index/callback/wxnotice';//通知url
		$data['trade_type'] = 'JSAPI';
		$data['openid'] = $orderinfo['user_id'];//用户标识
		
		$wxkey="asdfaASDFASDFASFasfsadf6546A84SA";
		$data['sign'] = $this->MakeSign($data,$wxkey);//签名
		// return json(['info' => $data]);
		//输出xml字符
		Log::write($data,"total_fee");
		$xml = $this->ToXml($data);
		
		$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
		//CURL模拟请求
		$curls = curl_init(); //启动一个CURL会话
		curl_setopt($curls, CURLOPT_URL, $url); //要访问的地址
		curl_setopt($curls, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($curls, CURLOPT_SSL_VERIFYHOST, FALSE);
		curl_setopt($curls, CURLOPT_HEADER, FALSE);//设置header
		curl_setopt($curls, CURLOPT_RETURNTRANSFER, TRUE);//要求结果为字符串且输出到屏幕上
		curl_setopt($curls, CURLOPT_POST, TRUE); //发送一个常规的Post请求
		curl_setopt($curls, CURLOPT_POSTFIELDS, $xml); //Post提交的数据包
		curl_setopt($curls, CURLOPT_TIMEOUT, 30); //设置超时限制防止死循环
		$payInfo = curl_exec($curls); //执行操作
		// $err = curl_error($curls);//输出错误
		curl_close($curls); //关闭CURL会话
		
		 //$payInfo = (new wechatService())->post_curl_data($url,$xml);
		$payInfo = json_decode(json_encode(simplexml_load_string($payInfo, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
		header("Content-type:text/html;charset=utf8");
		
		if($payInfo['return_code'] !== 'SUCCESS'){
			//return json(['info' => $payInfo]);
			Log::write($payInfo,"123456");
			return json(['info' => $payInfo['return_msg']]);
		}else{
			//添加进数据库
		    unset($orderinfo["id"]);
		    $order=$orderinfo;
			$order['out_trade_no'] = $data['out_trade_no'];
		    $order['tradeno'] = $data['out_trade_no'];
			$order["subject"]=$data['body'];
			$res=Db::table("car_order_pay")->insert($order);
			if($res){
			    $jsApiParameters['appId'] = $payInfo['appid'];
				$jsApiParameters['timeStamp'] = time();
				$jsApiParameters['timeStamp'] = '$jsApiParameters["timeStamp"]';
				$jsApiParameters['nonceStr'] = $this->createNoncestr();
				$jsApiParameters['package'] = 'prepay_id='.$payInfo['prepay_id'];
				$jsApiParameters['signType'] = 'MD5';
				$jsApiParameters['paySign'] = $this->MakeSigns($jsApiParameters,$wxkey);
				return json(['jsApiParameters' => json_encode($jsApiParameters)]);
			}else{
				return json(['info' => '订单存储失败']);
			}
		}   
	}
	
	
	//产生随机字符串，不长于32位
    private function createNoncestr($length = 32){
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++)
        {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }

        return $str;
    }
	
	//生成签名
    private function MakeSign($arr,$wxkey){
        //签名步骤一：按字典序排序参数
        ksort($arr);
        $string = $this->ToUrlParams($arr);
        //签名步骤二：在string后加入KEY
        $string = $string . "&key=" . $wxkey;
        //签名步骤三：MD5加密
        $string = md5($string);
        //签名步骤四：所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }
	
	//生成签名
    private function MakeSigns($arr,$wxkey){
        //签名步骤一：按字典序排序参数
        ksort($arr);
        $string = $this->ToUrlParams($arr);
        //签名步骤二：在string后加入KEY
        $string = $string . "&key=" . $wxkey;
        //签名步骤三：MD5加密
        $result = md5($string);
        return $result;
    }

    //输出xml字符
    private function ToXml($arr){
        $xml = "<xml>";
        foreach ($arr as $key => $val){
            if (is_numeric($val)){
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            }else{
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
        }
        $xml .= "</xml>";
        return $xml;
    }
	    //格式化参数格式化成url参数
    private function ToUrlParams($value){
        $buff = "";
        foreach($value as $k => $v){
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }
    function getJson($url){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        curl_close($ch);
        return json_decode($output, true);
    } 
}